module demo //模块开始
(
     input           clk,
    input           rst_n,
    input   [3:0]   i_data,
    input   [3:0]   q_data,
    input           ready_in,
    input   [1:0]   sel,
    output  [4:0]   out_data,
    output          ready_out      
);

    reg [3:0] i_data_reg;
    reg [3:0] q_data_reg;
    reg [3:0] out_data_reg;

    reg [3:0] cnt;

    //计数器
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            cnt<=4'b0;
        
        else if(cnt==4'd8)
            cnt<=4'b0;
        
        else 
            cnt<=cnt+1'b1;
    end

    //reg in
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            i_data_reg<=4'd0;
        else if(cnt==4'd4)
            i_data_reg<=4'd3;
        else if(ready_in)
            i_data_reg<=i_data;
    end
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            q_data_reg<=4'd0;
        else if(cnt==4'd4)
            q_data_reg<=4'd3;
        else if(ready_in)
            q_data_reg<=q_data;
    end  

//-------------------------------------写法1------------------------------------------//
/*
    //MUX
    always @(*) begin
        case (sel)
            2'b00:  out_data_reg = i_data_reg;
            2'b01:  out_data_reg = i_data_reg * q_data_reg;
            2'b10:  out_data_reg = i_data_reg & q_data_reg;
            2'b11:  out_data_reg = i_data_reg && q_data_reg;
            default:;
        endcase
    end

    assign out_data = out_data_reg;
    assign ready_out = ready_in;
*/

//-------------------------------------写法2------------------------------------------//

    //MUX
    assign out_data = (sel==2'b00) ?  i_data_reg : 
                      (sel==2'b01) ? (i_data_reg * q_data_reg) :
                      (sel==2'b10) ? (i_data_reg & q_data_reg) :
                                     (i_data_reg && q_data_reg);
    assign ready_out = ready_in;

endmodule